package cn.edu.sjtu.se.dslab.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import cn.edu.sjtu.se.dslab.action.bean.PageBean;
import cn.edu.sjtu.se.dslab.auth.CommonVariableModel;
import cn.edu.sjtu.se.dslab.auth.Group;
import cn.edu.sjtu.se.dslab.auth.User;
import cn.edu.sjtu.se.dslab.exception.DBException;
import cn.edu.sjtu.se.dslab.service.IAuthService;
import cn.edu.sjtu.se.dslab.service.IUserService;
import cn.edu.sjtu.se.dslab.util.Const;

@Controller
public class UserController {
	
	@Resource(name = "authService")
	IAuthService authService;
	
	@Resource(name = "userService")
	IUserService userService;

	@RequestMapping(value = "/user/update/password", method = RequestMethod.GET)
	public String updatePassword() {
		return "update_pwd";
	}
	
	@RequestMapping(value = "/user/{id}/reset/password", method = RequestMethod.GET)
	public String resetPassword(@PathVariable(value = "id") long id) {
		User temp = authService.getUserById(id);
		String newPassword = new SimpleHash("MD5", Const.PASSWORD).toHex();
		temp.setPassword(newPassword);
		authService.updateUser(temp);
		return "redirect:/user/" + id;
	}
	
	@RequestMapping(value = "/user/update/password", method = RequestMethod.POST)
	public ModelAndView updatePassword(@RequestParam String password, 
			@RequestParam String newPassword) {
		// set view
		Subject user = SecurityUtils.getSubject();
		ModelAndView mav = new ModelAndView();
		if (user!= null && user.getPrincipals() != null) {
			CommonVariableModel model = (CommonVariableModel) user.getPrincipals()
							.getPrimaryPrincipal();
			String temp = new SimpleHash("MD5", password).toHex();
			if (model.getUser().getPassword().equals(temp)) {
				temp =  new SimpleHash("MD5", newPassword).toHex();
				model.getUser().setPassword(temp);
				User user2 = authService.getUserById(model.getUser().getId());
				user2.setPassword(temp);
				authService.updateUser(user2);
				mav.setViewName("user_detail");
				List<Group> groupsList = authService.getAllGroups();
				System.out.println("groupsList size:"+groupsList.size());
				mav.addObject("groupsList", groupsList);
				mav.addObject("user", user2);
				mav.addObject("flag", 1);
			}else {
				mav.setViewName("update_pwd");
				mav.addObject("errormsg", "原始密码输入错误");
			}
			return mav;
		}else {
				mav.setViewName("login");
				return mav;
		}
	}
	
	@RequestMapping(value = "/user/{id}/update", method = RequestMethod.GET)
	public ModelAndView updateInfo(@PathVariable(value = "id") long id) {
		// set view
		ModelAndView mav = new ModelAndView();
		mav.setViewName("update_user");
		List<Group> groupsList = authService.getAllGroups();
		System.out.println("groupsList size:"+groupsList.size());
		mav.addObject("groupsList", groupsList);
		mav.addObject("user", authService.getUserById(id));
		return mav;
	}
	
	@RequestMapping(value = "/user/{id}/update", method = RequestMethod.POST)
	public String updateInfo(@PathVariable(value = "id") long id,@RequestParam String email,
			@RequestParam String staffnum, @RequestParam String realname) {
		User user = authService.getUserById(id);
		user.setEmail(email);
		user.setStaffNum(staffnum);
		user.setRealname(realname);
		authService.updateUser(user);
		return "redirect:/user/" + id;
	}
	
	@RequestMapping(value = "/user/list", method = RequestMethod.GET)
	public ModelAndView getUserList(@RequestParam(value = "pageNum", defaultValue = "1") int pageNum) throws DBException{
		PageBean<User> userBean = authService.getUserByPage(pageNum, Const.PAGESIZE);
		ModelAndView model = new ModelAndView();
		model.setViewName("user_list");
		model.addObject("bean", userBean);
		return model;
	}
	
	@RequestMapping(value = "/user/search", method = RequestMethod.GET)
	public ModelAndView searchUserList(){
		ModelAndView model = new ModelAndView();
		model.setViewName("user_list");
		model.addObject("flag", 1);
		return model;
	}
	
	@RequestMapping(value = "/user/search", method = RequestMethod.POST)
	public ModelAndView searchUserList(@RequestParam String searchText) throws DBException{
		List<User> userBean = userService.searchUserPageBeanByProperty(searchText);
		ModelAndView model = new ModelAndView();
		model.setViewName("user_list_nopage");
		model.addObject("bean", userBean);
		return model;
	}
	private final static String USERNAME = "username";

	private final static String ID = "id";

	private final static String REALNAME = "realname";

	@RequestMapping(value = "/user/search/json", method = RequestMethod.GET)
	@ResponseBody
	public Map<String, Object> searchUserListToJson(@RequestParam String searchText) throws DBException{
		List<User> userBean = userService.searchUserPageBeanByProperty(searchText);
		Map<String, Object> modelMap = new HashMap<String, Object>(2);
		List<Map<String, String>> data = new ArrayList<Map<String, String>>();
		if (userBean != null) {
			for (int i = 0; i < userBean.size(); i++) {
				Map<String, String> map = new HashMap<String, String>();
				map.put(USERNAME, userBean.get(i).getUsername());
				map.put(ID, ""+userBean.get(i).getId());
				map.put(REALNAME, userBean.get(i).getRealname());
				data.add(map);
			}
		}
		modelMap.put("data", data);
		modelMap.put("success", "true");
		return modelMap;
	}
	
	@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
	public ModelAndView userView(@PathVariable(value = "id") long id) {
		// set view
		ModelAndView mav = new ModelAndView();
		mav.setViewName("user_detail");
		List<Group> groupsList = authService.getAllGroups();
		System.out.println("groupsList size:"+groupsList.size());
		mav.addObject("groupsList", groupsList);
		// business logic
		mav.addObject("user", authService.getUserById(id));
		return mav;
	}
	
	@RequestMapping(value = "/user/info", method = RequestMethod.GET)
	public ModelAndView getCurrentUserView() {
		// set view
		Subject user = SecurityUtils.getSubject();
		ModelAndView mav = new ModelAndView();
		if (user!= null && user.getPrincipals() != null) {
			CommonVariableModel model = (CommonVariableModel) user.getPrincipals()
					.getPrimaryPrincipal();
			mav.setViewName("user_detail");
			List<Group> groupsList = authService.getAllGroups();
			mav.addObject("groupsList", groupsList);
			mav.addObject("flag", 1);
			// business logic
			mav.addObject("user", model.getUser());
			return mav;
		}else {
			mav.setViewName("login");
			return mav;
		}
	}
	
	@RequestMapping(value = "/user/{id}/group/add", method = RequestMethod.POST)
	public String userAddGroup(@PathVariable(value = "id") long id,
			@RequestParam long[] ids) {
		List<Group> groupsList = authService.getAllGroups();
		User user = authService.getUserById(id);
		Set<Group> oldList = user.getGroupsList();
		if (oldList == null) {
			oldList = new HashSet<Group>();
			user.setGroupsList(oldList);
		}
		oldList.clear();
		for (long i : ids) {
			for (Group group : groupsList) {
				if (group.getId() == i) {
					oldList.add(group);
					break;
				}
			}
		}
		authService.updateUser(user);
		return "redirect:/user/" + id;
	}
}
